const assert = require('assert');
const BaseController = require('./base');

module.exports = class extends BaseController {
  constructor(ctx, modelName = null) {
    super(ctx);
    this.resource = this.getResource();

    // think.logger.debug('resource:',this.resource);

    this.id = this.getId();
    assert(think.isFunction(this.model), 'this.model must be a function');
    this.modelInstance = this.model(modelName || this.resource);
  }

  async __before(action) {
    try {
      this.userInfo = await this.ctx.session('userInfo');
    } catch (err) {
      this.userInfo = {};
    }
    // if (this.resource !== 'token' && this.ctx.method.toUpperCase() !== 'GET' && think.isEmpty(this.userInfo)) {
    //  this.ctx.status = 401;
    //  return this.ctx.fail(-1, '请登录后操作');
    // }
  }

  // 请求的路径格式：
  // http://www.zengqs.com:8360/admin/esc/company/1 GET
  // http://www.zengqs.com:8360/admin/esc/company?page=3&pageSize=10 GET
  // http://www.zengqs.com:8360/admin/esc/company/1 DELETE，POST，PUT

  getResource() {
    think.logger.debug('controller:', this.ctx.controller);
    return this.ctx.controller.split('/').slice(-1)[0];
  }

  getId() {
    const id = this.get('id');
    if (id && (think.isString(id) || think.isNumber(id))) {
      return id;
    }
    const last = this.ctx.path.split('/').slice(-1)[0];
    if (last !== this.resource) {
      return last;
    }
    return '';
  }

  /**
   * 如果要支持多种接口，可以指定method参数，通过改参数赖区分不同功能
   * @returns {Promise<any | never | void>}
   */
  async getAction() {
    const map = {};
    let data;

    // 查询单一记录，指定id参数
    const pk = this.modelInstance.pk;
    if (this.id) {
      data = await this.modelInstance.where({[pk]: this.id}).find();
      return this.success(data);
    }

    // 查询一个集合，默认查询当前资源，不垮表，如果要跨表需要重载该方法
    const page = this.get('page');// 页码
    if (page) { // 分页查找
      const pageSize = this.get('pageSize') || 10;// 每页显示数量
      data = await this.modelInstance.where(map).page(page, pageSize).order(pk + ' desc').countSelect();
    } else { // 不分页
      data = await this.modelInstance.order(pk + ' desc').select();
    }
    return this.success(data);
  }

  async postAction() {
    const pk = this.modelInstance.pk;
    const data = this.post();
    delete data[pk];
    if (think.isEmpty(data)) {
      return this.fail('data is empty');
    }
    const insertId = await this.modelInstance.add(data);
    if (insertId) {
      data[pk] = insertId;
      // await this.hook(this.resource + 'Create', data);
    } else {
      return this.success({id: insertId});
    }
  }

  async deleteAction() {
    if (!this.id) {
      return this.fail('params error');
    }
    const pk = this.modelInstance.pk;
    const rows = await this.modelInstance.where({[pk]: this.id}).delete();
    if (rows) {
      // await this.hook(this.resource + 'Delete', {[pk]: this.id});
      return this.success({affectedRows: rows}, '删除成功');
    } else {
      return this.fail(1000, '删除失败');
    }
  }

  async putAction() {
    if (!this.id) {
      return this.fail('params error');
    }
    const pk = this.modelInstance.pk;
    const data = this.post();
    data[pk] = this.id;
    if (think.isEmpty(data)) {
      return this.fail('data is empty');
    }
    const rows = await this.modelInstance.where({[pk]: this.id}).update(data);
    if (rows) {
      // await this.hook(this.resource + 'Update', data);
      return this.success({affectedRows: rows}, '更新成功');
    } else {
      return this.fail(1000, '更新失败');
    }
  }

  async patchAction() {
    return this.fail(1000, '不支持该操作');
  }

  __call() {

  }
};
